import javax.microedition.lcdui.*;
import javax.microedition.midlet.MIDlet;

/**
 * Created by IntelliJ IDEA.<br>
 * User: maxim<br>
 * Date: Feb 21, 2010<br>
 * Time: 9:21:27 PM<br>
 * <p/>
 * <p/>
 * MobGraphBuilder - mobile graphics builder<br>
 * Copyright (C) 2010  Maxim Bondarenko<br>
 * <p/>
 * This program is free software: you can redistribute it and/or modify<br>
 * it under the terms of the GNU General Public License as published by<br>
 * the Free Software Foundation, either version 3 of the License, or<br>
 * (at your option) any later version.<br>
 * <br>
 * This program is distributed in the hope that it will be useful,<br>
 * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
 * GNU General Public License for more details.<br>
 * <br>
 * You should have received a copy of the GNU General Public License<br>
 * along with this program.  If not, see <a href="http://www.gnu.org/licenses/">GNU Licenses</a><br>
 */

public class MobGraphBuilder extends MIDlet implements CommandListener{
    private Command exitMidlet = new Command("Exit", Command.EXIT, 0);

    private Command showRes = new Command("Result", Command.SCREEN, 0);

    private Command getData = new Command("Enter", Command.SCREEN, 0);

    // Form object
    private Form myForm;
    // mydisplay object, perform phone display
    private Display mydisplay;

    private TextField[][] fields;

    private TextField equationNumField;

    private int equationsNum;

    private float[][] matrix;

    private int otv[];

    private static int MAX_EQUATIONS_NUM = 50;

    public MobGraphBuilder() {
        mydisplay = Display.getDisplay(this);
    }

    public void startApp() {
        Line myLine = new Line();
        myLine.addCommand(exitMidlet);
        myLine.setCommandListener(this);
        Display.getDisplay(this).setCurrent(myLine);
    }

    /*private TextField[][] createInputFields(Form dataForm) {
        TextField[][] fields = new TextField[equationsNum][equationsNum + 1];

        for (int i = 0; i < equationsNum; i++) {
            dataForm.append(new StringItem("Next equation", ""));
            for (int j = 0; j < equationsNum; j++) {
                fields[i][j] = new TextField("x" + j, "", 5, TextField.DECIMAL);
                dataForm.append(fields[i][j]);
            }
            fields[i][equationsNum] = new TextField("b", "", 5, TextField.DECIMAL);
            dataForm.append(fields[i][equationsNum]);
        }

        return fields;
    } */

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public void commandAction(Command c, Displayable d) {
        // выход из приложения
        if (c == exitMidlet) {
            destroyApp(false);
            notifyDestroyed();
        }
        if (c == showRes) {
            //solving the system
            //checking for equations nom
            if (equationsNum > MAX_EQUATIONS_NUM) {
                //todo add some output message
                System.out.println("Too many equations...");
            } else {
                //float[][] matrix = getRes(equationsNum);
                //matrix = getRes(equationsNum);
                //int otv[] = new int[equationsNum];
                otv = new int[equationsNum + 1];
                for (int i = 0; i < equationsNum + 1; i++) {
                    otv[i] = i;
                }

                //Прямой ход метода Гаусса
                System.out.println("Direct way...");
                for (int k = 0; k < equationsNum; k++) { //На какой позиции должен стоять главный элемент
                    System.out.println("k = " + k);
                    //glavelem(k, equationsNum); //Установка главного элемента
                    if (Math.abs(matrix[k][k]) < 0.0001) {
                        //printf("Система не имеет единственного решения");
                        //return (0);
                        //todo add some output message
                        System.out.println("No single solve");
                    }

                    System.out.println("Some division...");
                    for (int j = equationsNum; j >= k; j--) {
                        matrix[k][j] /= matrix[k][k];
                    }

                    System.out.println("");
                    for (int i = k + 1; i < equationsNum; i++) {
                        for (int j = equationsNum; j >= k; j--) {
                            matrix[i][j] -= matrix[k][j] * matrix[i][k];
                        }
                    }
                }

                //Обратный ход
                System.out.println("Reverse way...");
                double x[] = new double[equationsNum];
                for (int i = 0; i < equationsNum; i++) {
                    x[i] = matrix[i][equationsNum];
                }
                for (int i = equationsNum - 2; i >= 0; i--) {
                    for (int j = i + 1; j < equationsNum; j++) {
                        x[i] -= x[j] * matrix[i][j];
                    }
                }

                double reses[] = new double[equationsNum];
                int currRoot = 0;
                for (int i = 0; i < equationsNum; i++) {
                    for (int j = 0; j < equationsNum; j++) {
                        if (i == otv[j]) { //Расставляем корни по порядку
                            //printf("%f\n", x[j]);
                            reses[currRoot] = x[j];
                            break;
                        }
                    }
                }

                //showing reses
                Form resForm = new Form("Result");
                for (int i = 0; i < equationsNum; i++) {
                    resForm.append(new StringItem("x" + i + "=", String.valueOf(reses[i])));
                }
                resForm.addCommand(exitMidlet);
                resForm.setCommandListener(this);
                mydisplay.getDisplay(this).setCurrent(resForm);
            }
        }
        /*if (c == getData) {
            equationsNum = Integer.valueOf(equationNumField.getString()).intValue();
            Form dataForm = new Form("Get data");
            fields = createInputFields(dataForm);
            //dataForm.append(fields);
            dataForm.addCommand(exitMidlet);
            dataForm.addCommand(showRes);
            dataForm.setCommandListener(this);
            mydisplay.getDisplay(this).setCurrent(dataForm);
        }*/
    }

    /*void glavelem(int k, int n) {
        int i, j, i_max = k, j_max = k;
        float temp;
        //Ищем максимальный по модулю элемент
        System.out.println("Searching max abs element");
        for (i = k; i < n; i++) {
            for (j = k; j < n; j++) {
                if (Math.abs(matrix[i_max][j_max]) < Math.abs(matrix[i][j])) {
                    i_max = i;
                    j_max = j;
                }
            }
        }

        //Переставляем строки
        System.out.println("Lines moving...");
        for (j = k; j < n + 1; j++) {
            temp = matrix[k][j];
            matrix[k][j] = matrix[i_max][j];
            matrix[i_max][j] = temp;
        }

        //Переставляем столбцы
        System.out.println("Column moving...");
        for (i = 0; i < n; i++) {
            temp = matrix[i][k];
            matrix[i][k] = matrix[i][j_max];
            matrix[i][j_max] = temp;
        }

        //Учитываем изменение порядка корней
        System.out.println("Otv changing...");
        i = otv[k];
        otv[k] = otv[j_max];
        otv[j_max] = i;
    }

    private float[][] getRes(int equationsNum) {
        float[][] matrix = new float[equationsNum][equationsNum + 1];
        for (int i = 0; i < equationsNum; i++) {
            for (int j = 0; j < equationsNum + 1; j++) {
                matrix[i][j] = Float.valueOf(fields[i][j].getString()).floatValue();
            }
        }

        for (int i = 0; i < equationsNum; i++) {
            for (int j = 0; j < equationsNum + 1; j++) {
                //System.out.println(matrix[i][j]);
            }
        }

        return matrix;
    } */
}
